package eu.irreality.dai.gameplay.entities;

import java.awt.Color;
import java.util.LinkedList;
import java.util.List;

import eu.irreality.dai.fov.LOSCriterion;
import eu.irreality.dai.gameplay.world.GameWorld;
import eu.irreality.dai.util.Debug;
import eu.irreality.dai.util.Observable;
import eu.irreality.dai.util.Observer;
import eu.irreality.dai.util.Position;
import eu.irreality.dai.world.level.Level;

/**
 * PlayerCharacter is a particular AliveEntity. That is, the entity handled by
 * the player in a normal game.
 * 
 */
public class PlayerCharacter extends AliveEntity implements Observable
{

    private List<Observer> observers = new LinkedList<Observer>();

    public PlayerCharacter()
    {
	this.displayPriority = 200;
    }

    public PlayerCharacter(char c, Color color)
    {
	this();
	this.c = c;
	this.color = color;
    }

    public void update(PropertyEntry pe, GameWorld world)
    {
	Debug.println("Updating " + pe);
	if (pe.getName().equals("monster_action"))
	{
	    // updateSeen(world.getActiveLevel());
	    notifyObservers("waiting_for_key");
	    // TODO: Later, this will be done by the action:
	    setProperty("monster_action", "idle", 10);
	    updateSeen(world.getActiveLevel());
	}
    }

    public void notifyObservers(Object arg)
    {
	for (Observer o : observers)
	{
	    o.update(this, arg);
	}

    }

    public void notifyObservers()
    {
	notifyObservers(null);
    }

    public void addObserver(Observer o)
    {
	observers.add(o);
    }

    public void updateSeen(Level l)
    {
	LOSCriterion lc = getLOSCriterion();
	for (int r = 0; r < l.getRows(); r++)
	{
	    for (int c = 0; c < l.getCols(); c++)
	    {
		Position pos = new Position(r, c);
		if (!l.isSeen(pos))
		{
		    if (pos == this.getPosition())
			l.markPositionAsSeen(pos, true);
		    else if (lc.isInLOS(l, this.getPosition(), pos))
			l.markPositionAsSeen(pos, true);
		}
	    }
	}
    }

}
